// red位置
var position1 = {
    x: 0,
    y: 0
}
// green位置
var position2 = {
    x: 0,
    y: 0
}
// redBuff
var buff1={
    power:1,
    life:1
}
// greenBuff
var buff2={
    power:0,
    life:1
}
// 炸弹数组
var timeA = new Array(3)
var timeB = new Array(3)
var player1Time,player2Time
// 炸弹位置
var bouncePosition = []
var judgeArr=[]
// 禁止生成箱子的位置
var cannotArr=[
    [0,0],[0,1],[0,2],[1,0],[2,0],[9,9],[9,8],[9,7],[8,9],[7,9]
]
// 固定物
var fixArr = []
// 可毁物
var ruinArr = []
// 加生命
var lifeArr=[]
// 加威力
var powerArr=[]
// 深拷贝动态数组
var deepRuin,deepLife,deepPower;
// 地图行列
var w = 0;
var h = 0
// 生成地图
function add(m, n) {
    w = m;
    h = n;
    position2.x = m - 1;
    position2.y = n - 1;
    for (var i = 0; i < m; i++) {
        for (var j = 0; j < n; j++) {
            $('#content').append('<div class="box" data-X='+j+' data-Y='+i+'></div>')
        }
    }
}
// 生成盒子
function addBox(ele,arr){
    for(var i=0;i<arr.length;i++){
        $("#content").append('<div class='+ele+' data-id='+i+'></div>')
    }
    $("."+ele).each(function() {
        var ids = $(this).data("id")
        var eleLeft = arr[ids][0]
        var eleTop = arr[ids][1]
        $(this).css("left", 46 * eleLeft + "px").css("top", 10 + 46 * eleTop + "px")
    })
}
// 深拷贝
function deepCopy(copyArr) {
    var newArr = []
    for (var d = 0; d < copyArr.length; d++) {
        let [...arr] = copyArr[d]
        newArr.push(arr)
    }
    return newArr
}
// red生成
function player1() {
    $('#content').append('<div id="player1" class="player1"></div>')
    $("#player1").css("left", "8px").css("top", "18px"); //
}
// green生成
function player2() {
    $('#content').append('<div id="player2" class="player2"></div>')
    $("#player2").css("left", "422px").css("top", "432px");
}
// 检测二维数组是否有某个数组
function detect(x,y,arr){
    var flag=false
    for(var j=0;j<arr.length;j++){
        if(arr[j][0]==x && arr[j][1]==y){
            flag=true
            break
        }
    }
    return flag
}
// 获取二维数组元素下标
function getIndex(x, y, arr) {
    var index = null
    for (var i = 0; i < arr.length; i++) {
        if (arr[i][0] == x && arr[i][1] == y) {
            index = i
            break
        }
    }
    return index
}
// 固定物生成
function addFix() {
    for(var i=0;i<10;i++){
        var x=Math.floor(Math.random()*10);
        var y=Math.floor(Math.random()*10);
        if(!detect(x,y,fixArr) && !detect(x,y,cannotArr)){
            fixArr.push([x,y])
        }else{
            i--
        }
    }
    addBox("fix",fixArr)
}
// 可毁物生成
function addRuin(){
    for(var i=0;i<10;i++){
        var x=Math.floor(Math.random()*10);
        var y=Math.floor(Math.random()*10);
        if(!detect(x,y,fixArr) && !detect(x,y,cannotArr) && !detect(x,y,ruinArr)){
            ruinArr.push([x,y])
        }else{
            i--
        }
    }
    deepRuin=deepCopy(ruinArr)
	addBox("ruin",ruinArr)
}
// 生命buff
function addLife(){
    for(var i=0;i<5;i++){
        lifeArr.push(ruinArr[i])
    }
    deepLife=deepCopy(lifeArr)
    addBox("life",lifeArr)
}
// 威力buff
function addPower(){
    for(var i=5;i<10;i++){
        powerArr.push(ruinArr[i])
    }
    deepPower=deepCopy(powerArr)
    addBox("power",powerArr)
}
// 判断小球移动位置是否有阻碍物
function moveJudge(x, y,buff) {
    var flag = false
    for (var i = 0; i < fixArr.length; i++) {
        if (fixArr[i][0] == x && fixArr[i][1] == y) {
            flag = true
            break
        }
    }
    //移动位置是否有可毁物
    if (!flag) {
        for (var j = 0; j < ruinArr.length; j++) {
            if (ruinArr[j][0] == x && ruinArr[j][1] == y) {
                flag = true
                break
            }
        }
    }
    // 移动位置是否有生命buff
    if(!flag){
        for(var i=0;i<lifeArr.length;i++){
            if(lifeArr[i][0] == x && lifeArr[i][1] == y){
                var deepIndex=getIndex(lifeArr[i][0],lifeArr[i][1],deepLife)
                lifeArr.splice(i,1)
                i--
                $(".life[data-id="+deepIndex+"]").remove()
                buff.life++;
                show()
            }
        }
    }
    // 移动位置是否有威力buff
    if(!flag){
        for(var i=0;i<powerArr.length;i++){
            if(powerArr[i][0] == x && powerArr[i][1] == y){
                var deepIndex=getIndex(powerArr[i][0],powerArr[i][1],deepPower)
                powerArr.splice(i,1)
                i--
                $(".power[data-id="+deepIndex+"]").remove()
                buff.power++;
                show()
            }
        }
    }
    return flag
}
// 小球移动
function move() {
    $(document).keydown(function(e) {
        switch (e.keyCode) {
            // red向上（w）
            case 87:
                if (position1.y > 0) {
                    if (!moveJudge(position1.x, position1.y-1,buff1)) {
                        position1.y--;
                        $("#player1").css("top", 18 + 46 * (position1.y) + "px")
                    }
                }
                break;
                // red向下（s）
            case 83:
                if (position1.y < h - 1) {
                    if (!moveJudge(position1.x, position1.y+1,buff1)) {
                        position1.y++;
                        $("#player1").css("top", 18 + 46 * (position1.y) + "px")
                    }
                }
                break;
                // red向左（a）
            case 65:
                if (position1.x > 0) {
                    if (!moveJudge(position1.x-1 , position1.y,buff1)) {
                        position1.x--;
                        $("#player1").css("left", 8 + 46 * (position1.x) + "px")
                    }
                }
                break;
                // red向右（d）
            case 68:
                if (position1.x < w - 1) {
                    if (!moveJudge(position1.x+1 , position1.y,buff1)) {
                        position1.x++;
                        $("#player1").css("left", 8 + 46 * (position1.x) + "px")
                    }
                }
                break;
                // red放炸弹（空格）
            case 32:
                var ballX = $("#player1").css('left')
                var ballY = $("#player1").css("top")
                bouncePosition.push([position1.x, position1.y])
                bounce("timeA", timeA, ballX, ballY,buff1,position1.x,position1.y)
                break;
                // green向上（↑）
            case 38:
                if (position2.y > 0) {
                    if (!moveJudge(position2.x, position2.y-1,buff2)) {
                        position2.y--;
                        $("#player2").css("top", 18 + 46 * (position2.y) + "px")
                    }
                }
                break;
                // green向下（↓）
            case 40:
                if (position2.y < h - 1) {
                    if (!moveJudge(position2.x, position2.y+1 ,buff2)) {
                        position2.y++;
                        $("#player2").css("top", 18 + 46 * (position2.y) + "px")
                    }
                }
                break;
                // green向左（←）
            case 37:
                if (position2.x > 0) {
                    if (!moveJudge(position2.x-1 , position2.y,buff2)) {
                        position2.x--;
                        $("#player2").css("left", 8 + 46 * (position2.x) + "px")
                    }
                }
                break;
                // green向右（→）
            case 39:
                if (position2.x < w - 1) {
                    if (!moveJudge(position2.x+1, position2.y,buff2)) {
                        position2.x++;
                        $("#player2").css("left", 8 + 46 * (position2.x) + "px")
                    }
                }
                break;
                // green放炸弹（0）
            case 96:
                var ball2X = $("#player2").css('left')
                var ball2Y = $("#player2").css("top")
                bouncePosition.push([position2.x, position2.y])
                bounce("timeB", timeB, ball2X, ball2Y,buff2,position2.x,position2.y)
                break;
        }
    })
}
// 炸弹爆炸
function bounce(ele, time, ballLeft, ballTop,buff,X,Y){
    for(var i=0;i<time.length;i++){
        if(!time[i]){
            // 添加炸弹
            $("#content").append('<div class=' + ele + ' data-id=' + i + '></div>')
            // 炸弹位置
            $("." + ele + "[data-id=" + i + "]").css("left", ballLeft).css("top", ballTop)
            //炸弹定时器
            time[i]=setTimeout(function(){
                // 添加爆炸样式
                $(".box[data-X="+X+"][data-Y="+Y+"]").addClass(ele+"Bounce")
                var n=0
                // 向炸弹四个方向添加爆炸样式
                while(n<4){
                    var nowX=X
                    var nowY=Y
                    var condition="LeftBounce"
                    // 添加距离不超过玩家buff
                    for(var l=0;l<=buff.power;l++){
                        if(n==0){
                            nowX--
                            if(nowX<0){
                                break
                            }
                            condition="LeftBounce"
                        }else if(n==1){
                            nowX++
                            if(nowX==w){
                                break
                            }
                            condition='RightBounce'
                        }else if(n==2){
                            nowY--
                            if(nowY<0){
                                break
                            }
                            condition="TopBounce"
                        }else{
                            nowY++
                            if(nowY==h){
                                break
                            }
                            condition="BottomBounce"
                        }
                        if(!detect(nowX,nowY,fixArr)){
                            $(".box[data-X="+nowX+"][data-Y="+nowY+"]").addClass(ele+condition)
                            if(detect(nowX,nowY,ruinArr)){
                                break
                            }    
                        }else{
                            break
                        }     
                    }
                    n++
                }
                judge(buff)
                
                setTimeout(function(){
                    compute()
                    $("#content").children("." + ele + "[data-id=" + i + "]").remove()
                    $(".box").removeClass(ele+"Bounce").removeClass(ele+"LeftBounce").removeClass(ele+"RightBounce").removeClass(ele+"TopBounce").removeClass(ele+"BottomBounce")
                    clearTimeout(time[i])
                    time[i]=null
                },200)
            },3000)
            break
        }
    }
}
// 判断炸弹爆炸是否触碰
function collision(x,y,buff){
    // 炸弹坐标
    var bounceX = bouncePosition[0][0]
    var bounceY = bouncePosition[0][1]
    var flagX=bounceX
    var flagY=bounceY
    for(var i=0;i<=buff.power+1;i++){
        // 检测坐标的x与炸弹坐标的x一致
        if(x== bounceX){
            // 从炸弹坐标向四周扩散计算
            // 当前坐标为可毁物坐标而且并非是要检测的坐标，炸弹只能穿透一个可毁物
            if(detect(x,flagY,judgeArr) && flagY!=y){
                return false
            }
            // 当前坐标为固定物坐标，炸弹无法穿透
            if(detect(x,flagY,fixArr)){
                return false
            }
            //  当前坐标为可毁物坐标而且是要检测的坐标
            else if(detect(x,flagY,judgeArr) && flagY==y){
                return true
            }else if(!detect(x,flagY,judgeArr) && flagY==y){
                return true
            }
            else{
                // 向上计算
                if(y<=bounceY){
                    flagY--
                }
                // 向下计算
                else{
                    flagY++
                }
            }
        }
        // 检测坐标的y与炸弹坐标的y一致
        else if(y== bounceY){
            if(detect(flagX,y,judgeArr) && flagX!=x){
                return false
            }
            if(detect(flagX,y,fixArr) && flagX!=x){
                return false
            }
            else if(detect(flagX,y,judgeArr) && flagX==x){
                return true
            }else if(!detect(flagX,y,judgeArr) && flagX==x){
                return true
            }
            else{
                if(x<=bounceX){
                    flagX--
                }else{
                    flagX++
                }
            }
        }
    }
}
// 触碰
function judge(buff) {
    var player1X = position1.x
    var player1Y = position1.y
    var player2X = position2.x
    var player2Y = position2.y
    // 可毁物被炸
    // 深拷贝每一次爆炸前存在的可毁物数组
    judgeArr=deepCopy(ruinArr)
    for(var i=0;i<ruinArr.length;i++){
        if(collision(ruinArr[i][0],ruinArr[i][1],buff)){
            var deepIndex=getIndex(ruinArr[i][0],ruinArr[i][1],deepRuin)
            ruinArr.splice(i,1)
            i--
            $(".ruin[data-id="+deepIndex+"]").remove()
        }
    }
    // palyer1被炸到
    if(collision(player1X,player1Y,buff)){
        if(!player1Time){
            buff1.life--;
        }
        if(buff1.life){
            player1Time=setTimeout(function(){
                clearTimeout(player1Time)
                player1Time=null
            },3000)
            position1.x=0
            position1.y=0    
            $("#player1").css("left", "8px").css("top", "18px"); 
        }
    }
    // player2被炸到
    if(collision(player2X,player2Y,buff)){
        if(!player2Time){
            buff2.life--;
        }
        if(buff2.life){
            player2Time=setTimeout(function(){
                clearTimeout(player2Time)
                player2Time=null
            })
            position2.x = w - 1;
            position2.y = h - 1;
            $("#player2").css("left", "422px").css("top", "432px");
        }    
    }
    bouncePosition.splice(0,1)
    show()
}
// 显示玩家数据
function show(){
    $(".player1Life").text("life:"+buff1.life)
    $(".player1Power").text("power:"+buff1.power)
    $(".player2Life").text("life:"+buff2.life)
    $(".player2Power").text("power:"+buff2.power)
}
// 清空炸弹
function clearTime(time){
    for(var i=0;i<time.length;i++){
        clearTimeout(time[i])
    }
}
// 计算结果
function compute(){
    if(!buff1.life && buff2.life){
        clearTime(timeA)
        clearTime(timeB)
        alert("player2 Win！")
        alert("重新开始")
        window.location.reload()
    }
    else if(buff1.life && !buff2.life){
        clearTime(timeA)
        clearTime(timeB)
        alert("player1 Win!")
        alert("重新开始")
        window.location.reload()
    }else if(!buff1.life && !buff2.life){
        clearTime(timeA)
        clearTime(timeB)
        alert("all Win!")
        alert("重新开始")
        window.location.reload()
    }
}

add(10, 10)
addFix()
addRuin()
addLife()
addPower()
player1()
player2()
move()
show()